package com.fairylove.rpc.transport.utils;

import com.fairylove.rpc.entity.RpcRequest;
import com.fairylove.rpc.entity.RpcResponse;
import com.fairylove.rpc.enums.PackageType;
import com.fairylove.rpc.serializer.CommonSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;

public class ObjectReader {
    private static final Logger logger = LoggerFactory.getLogger(ObjectReader.class);
    private static  final int MAGIC_NUMBER = 0xCAFEBABE;
      public static Object readObject(InputStream inputStream) throws IOException {
          byte []numbytes = new byte[4];
          //读进byte数组
          inputStream.read(numbytes);
          int magic = bytesToInt(numbytes);
          if(MAGIC_NUMBER != magic){
              logger.error("不识别的协议包magic:{}",magic);
          }
          inputStream.read(numbytes);
          int packageCode = bytesToInt(numbytes);
          Class<?> packageClass = null;
          if(packageCode == PackageType.REQUEST_PACK.getCode()){
              packageClass = RpcRequest.class;
          }else
              if(packageCode == PackageType.RESPONSE_PACK.getCode()){
                  packageClass = RpcResponse.class;
              }else{
                  logger.error("不识别的数据包 packageCode:{}",packageCode);
              }
          inputStream.read(numbytes);
          int serializeCode = bytesToInt(numbytes);
          CommonSerializer serializer = CommonSerializer.getByCode(serializeCode);
          if(serializer == null){
              logger.error("不识别的序列号：{}",serializeCode);
          }
          inputStream.read(numbytes);
          int length = bytesToInt(numbytes);
          byte[] bytes = new byte[length];
          inputStream.read(bytes);
          return  serializer.deserialize(bytes, packageClass);
      }

    public static int bytesToInt(byte[] src) {
        int value;
        value = ((src[0] & 0xFF)<<24)
                |((src[1] & 0xFF)<<16)
                |((src[2] & 0xFF)<<8)
                |(src[3] & 0xFF);
        return value;
    }

}
